import { useState, useCallback, useRef, useMemo } from 'react'
import { KafkaMessage } from '@/stores/kafkaStore'

interface VirtualizedState {
  scrollTop: number
  scrollHeight: number
  clientHeight: number
  isScrolling: boolean
}

interface UseVirtualizedMessagesOptions {
  itemHeight: number
  expandedItemHeight: number
  overscanCount?: number
  throttleMs?: number
}

interface UseVirtualizedMessagesReturn {
  virtualizedState: VirtualizedState
  visibleRange: { start: number; end: number }
  expandedRows: Record<string, boolean>
  toggleRow: (messageId: string) => void
  scrollToIndex: (index: number) => void
  scrollToTop: () => void
  scrollToBottom: () => void
  handleScroll: (scrollTop: number) => void
  getItemHeight: (index: number) => number
  getTotalHeight: (itemCount: number) => number
}

export function useVirtualizedMessages(
  messages: KafkaMessage[],
  options: UseVirtualizedMessagesOptions
): UseVirtualizedMessagesReturn {
  const {
    itemHeight,
    expandedItemHeight,
    overscanCount = 5,
    throttleMs = 16
  } = options

  const [virtualizedState, setVirtualizedState] = useState<VirtualizedState>({
    scrollTop: 0,
    scrollHeight: 0,
    clientHeight: 0,
    isScrolling: false
  })

  const [expandedRows, setExpandedRows] = useState<Record<string, boolean>>({})
  const scrollTimeoutRef = useRef<NodeJS.Timeout>()
  const lastScrollTime = useRef<number>(0)

  // 切换行展开状态
  const toggleRow = useCallback((messageId: string) => {
    setExpandedRows(prev => ({
      ...prev,
      [messageId]: !prev[messageId]
    }))
  }, [])

  // 获取单个项目的高度
  const getItemHeight = useCallback((index: number) => {
    if (index >= messages.length) return itemHeight
    
    const message = messages[index]
    const messageId = `${message.topic}-${message.partition}-${message.offset}-${index}`
    const isExpanded = expandedRows[messageId]
    
    return isExpanded ? expandedItemHeight : itemHeight
  }, [messages, expandedRows, itemHeight, expandedItemHeight])

  // 计算总高度
  const getTotalHeight = useCallback((itemCount: number) => {
    let totalHeight = 0
    for (let i = 0; i < itemCount; i++) {
      totalHeight += getItemHeight(i)
    }
    return totalHeight
  }, [getItemHeight])

  // 计算可见范围
  const visibleRange = useMemo(() => {
    const { scrollTop, clientHeight } = virtualizedState
    
    let startIndex = 0
    let endIndex = messages.length - 1
    let currentHeight = 0

    // 找到开始索引
    for (let i = 0; i < messages.length; i++) {
      const itemHeight = getItemHeight(i)
      if (currentHeight + itemHeight > scrollTop) {
        startIndex = Math.max(0, i - overscanCount)
        break
      }
      currentHeight += itemHeight
    }

    // 找到结束索引
    currentHeight = 0
    for (let i = 0; i < messages.length; i++) {
      if (i < startIndex) {
        currentHeight += getItemHeight(i)
        continue
      }
      
      const itemHeight = getItemHeight(i)
      if (currentHeight > clientHeight + overscanCount * itemHeight) {
        endIndex = Math.min(messages.length - 1, i + overscanCount)
        break
      }
      currentHeight += itemHeight
    }

    return { start: startIndex, end: endIndex }
  }, [virtualizedState, messages.length, getItemHeight, overscanCount])

  // 节流滚动处理
  const handleScroll = useCallback((scrollTop: number) => {
    const now = Date.now()
    
    // 节流处理
    if (now - lastScrollTime.current < throttleMs) {
      return
    }
    lastScrollTime.current = now

    setVirtualizedState(prev => ({
      ...prev,
      scrollTop,
      isScrolling: true
    }))

    // 清除之前的超时
    if (scrollTimeoutRef.current) {
      clearTimeout(scrollTimeoutRef.current)
    }

    // 设置滚动结束标志
    scrollTimeoutRef.current = setTimeout(() => {
      setVirtualizedState(prev => ({
        ...prev,
        isScrolling: false
      }))
    }, 150)
  }, [throttleMs])

  // 滚动到指定索引
  const scrollToIndex = useCallback((index: number) => {
    if (index < 0 || index >= messages.length) return

    let scrollTop = 0
    for (let i = 0; i < index; i++) {
      scrollTop += getItemHeight(i)
    }

    setVirtualizedState(prev => ({
      ...prev,
      scrollTop
    }))
  }, [messages.length, getItemHeight])

  // 滚动到顶部
  const scrollToTop = useCallback(() => {
    setVirtualizedState(prev => ({
      ...prev,
      scrollTop: 0
    }))
  }, [])

  // 滚动到底部
  const scrollToBottom = useCallback(() => {
    const totalHeight = getTotalHeight(messages.length)
    const { clientHeight } = virtualizedState
    
    setVirtualizedState(prev => ({
      ...prev,
      scrollTop: Math.max(0, totalHeight - clientHeight)
    }))
  }, [getTotalHeight, messages.length, virtualizedState.clientHeight])

  return {
    virtualizedState,
    visibleRange,
    expandedRows,
    toggleRow,
    scrollToIndex,
    scrollToTop,
    scrollToBottom,
    handleScroll,
    getItemHeight,
    getTotalHeight
  }
}

// 性能优化的消息比较函数
export function areMessagesEqual(
  prevMessages: KafkaMessage[],
  nextMessages: KafkaMessage[]
): boolean {
  if (prevMessages.length !== nextMessages.length) {
    return false
  }

  // 快速检查：比较前几条和后几条消息的关键字段
  const checkCount = Math.min(5, prevMessages.length)
  
  for (let i = 0; i < checkCount; i++) {
    const prev = prevMessages[i]
    const next = nextMessages[i]
    
    if (
      prev.topic !== next.topic ||
      prev.partition !== next.partition ||
      prev.offset !== next.offset ||
      prev.timestamp !== next.timestamp
    ) {
      return false
    }
  }

  // 检查末尾几条
  for (let i = Math.max(0, prevMessages.length - checkCount); i < prevMessages.length; i++) {
    const prev = prevMessages[i]
    const next = nextMessages[i]
    
    if (
      prev.topic !== next.topic ||
      prev.partition !== next.partition ||
      prev.offset !== next.offset ||
      prev.timestamp !== next.timestamp
    ) {
      return false
    }
  }

  return true
}

// 内存优化的消息缓存
export class MessageCache {
  private cache = new Map<string, any>()
  private maxSize: number
  private accessOrder: string[] = []

  constructor(maxSize: number = 1000) {
    this.maxSize = maxSize
  }

  get(key: string): any {
    const value = this.cache.get(key)
    if (value !== undefined) {
      // 更新访问顺序
      const index = this.accessOrder.indexOf(key)
      if (index > -1) {
        this.accessOrder.splice(index, 1)
      }
      this.accessOrder.push(key)
    }
    return value
  }

  set(key: string, value: any): void {
    // 如果已存在，更新值和访问顺序
    if (this.cache.has(key)) {
      this.cache.set(key, value)
      const index = this.accessOrder.indexOf(key)
      if (index > -1) {
        this.accessOrder.splice(index, 1)
      }
      this.accessOrder.push(key)
      return
    }

    // 如果缓存已满，删除最久未访问的项
    if (this.cache.size >= this.maxSize) {
      const oldestKey = this.accessOrder.shift()
      if (oldestKey) {
        this.cache.delete(oldestKey)
      }
    }

    this.cache.set(key, value)
    this.accessOrder.push(key)
  }

  clear(): void {
    this.cache.clear()
    this.accessOrder = []
  }

  size(): number {
    return this.cache.size
  }
}

// 创建全局消息缓存实例
export const messageCache = new MessageCache(2000)
